"""
API依赖项
"""

from typing import Annotated, Callable

from fastapi import Depends, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer

from app.core import settings
from app.core.config import Settings
from app.database.db import SessionDep
from app.database.redis import RedisDep
from app.exceptions.base import AppException
from app.models.system import SysUser
from app.service.auth_service import AuthService
from app.service.captcha_service import CaptchaService
from app.service.dept_service import DeptService
from app.service.dict_service import DictService
from app.service.log_service import LogService
from app.service.menu_service import MenuService
from app.service.role_service import RoleService
from app.service.token_service import TokenService
from app.service.user_role_service import UserRoleService
from app.service.user_service import UserService

# ==================== 基础配置依赖 ====================


def get_settings() -> Settings:
    """获取应用配置"""
    return settings


SettingsDep = Annotated[Settings, Depends(get_settings)]


# ==================== 认证相关依赖 ====================


def get_captcha_service(
    redis: RedisDep,
    settings: SettingsDep,
) -> CaptchaService:
    """创建并返回 CaptchaService 实例"""
    return CaptchaService(redis=redis, settings=settings)


CaptchaServiceDep = Annotated[CaptchaService, Depends(get_captcha_service)]


def get_token_service(redis: RedisDep, settings: SettingsDep) -> TokenService:
    """创建并返回 TokenService 实例"""
    return TokenService(redis=redis, settings=settings)


TokenServiceDep = Annotated[TokenService, Depends(get_token_service)]


def get_auth_service(
    redis: RedisDep, session: SessionDep, token_service: TokenServiceDep, settings: SettingsDep
) -> AuthService:
    """创建并返回 AuthService 实例"""
    return AuthService(redis=redis, session=session, token_service=token_service, settings=settings)


AuthServiceDep = Annotated[AuthService, Depends(get_auth_service)]


# ==================== 用户认证依赖 ====================

security = HTTPBearer()
TokenDep = Annotated[HTTPAuthorizationCredentials, Depends(security)]


async def get_current_active_user(token: TokenDep, auth_service: AuthServiceDep) -> SysUser:
    """
    解析并验证 JWT 令牌，返回当前用户信息

    Args:
        token: JWT令牌
        auth_service: 认证服务实例

    Returns:
        SysUser: 当前活跃用户对象

    Raises:
        AppException: 令牌无效或用户不存在
    """
    user = await auth_service.get_current_active_user(token.credentials)
    return user


CurrentUserDep = Annotated[SysUser, Depends(get_current_active_user)]


def get_current_active_superuser(current_user: CurrentUserDep) -> SysUser:
    """
    检查当前用户是否为超级管理员

    Args:
        current_user: 当前用户对象

    Returns:
        SysUser: 超级管理员用户对象

    Raises:
        AppException: 用户无角色或非管理员
    """
    # 获取用户角色信息
    roles = [role.code for role in current_user.roles]

    if not roles:
        raise AppException(code=f"E0{status.HTTP_403_FORBIDDEN}", message="用户无角色")

    # 检查用户是否为管理员
    if settings.ADMIN_ROLE_CODE not in roles:
        raise AppException(code=f"E0{status.HTTP_403_FORBIDDEN}", message="用户非管理员")

    return current_user


CurrentSuperUserDep = Annotated[SysUser, Depends(get_current_active_superuser)]


def require_permission(permission: str) -> Callable[[CurrentUserDep], SysUser]:
    """
    返回一个依赖函数，校验当前用户是否拥有指定权限

    Args:
        permission: 需要的权限字符串

    Returns:
        Callable: 权限检查函数

    Usage:
        current_user: User = Depends(require_permission("sys:user:add"))
    """

    async def _permission_checker(current_user: CurrentUserDep) -> SysUser:
        """权限检查内部函数"""
        # 获取用户角色信息
        roles = [role.code for role in current_user.roles]

        if not roles:
            raise AppException(code=f"E0{status.HTTP_403_FORBIDDEN}", message="用户无角色")

        # 检查用户是否为管理员（管理员拥有所有权限）
        if settings.ADMIN_ROLE_CODE in roles:
            return current_user

        # 获取菜单权限
        permissions = [menu.perm for role in current_user.roles for menu in role.menus if menu.perm]

        if not permissions:
            raise AppException(code=f"E0{status.HTTP_403_FORBIDDEN}", message="用户无菜单权限")

        if permission not in permissions:
            raise AppException(code=f"E0{status.HTTP_403_FORBIDDEN}", message=f"需要权限: '{permission}'")

        return current_user

    return _permission_checker


# ==================== 业务服务依赖 ====================


def get_user_service(redis: RedisDep, session: SessionDep, settings: SettingsDep) -> UserService:
    """创建并返回 UserService 实例"""
    return UserService(redis=redis, session=session, settings=settings)


UserServiceDep = Annotated[UserService, Depends(get_user_service)]


def get_user_role_service(session: SessionDep) -> UserRoleService:
    """创建并返回 UserRoleService 实例"""
    return UserRoleService(session=session)


UserRoleServiceDep = Annotated[UserRoleService, Depends(get_user_role_service)]


def get_dept_service(session: SessionDep) -> DeptService:
    """创建并返回 DeptService 实例"""
    return DeptService(session=session)


DeptServiceDep = Annotated[DeptService, Depends(get_dept_service)]


def get_role_service(session: SessionDep, redis: RedisDep, settings: SettingsDep) -> RoleService:
    """创建并返回 RoleService 实例"""
    return RoleService(session=session, redis=redis, settings=settings)


RoleServiceDep = Annotated[RoleService, Depends(get_role_service)]


def get_menu_service(session: SessionDep, role_service: RoleServiceDep) -> MenuService:
    """创建并返回 MenuService 实例"""
    return MenuService(session=session, role_service=role_service)


MenuServiceDep = Annotated[MenuService, Depends(get_menu_service)]


def get_log_service(session: SessionDep) -> LogService:
    """创建并返回 LogService 实例"""
    return LogService(session=session)


LogServiceDep = Annotated[LogService, Depends(get_log_service)]


def get_dict_service(session: SessionDep) -> DictService:
    """创建并返回 DictService 实例"""
    return DictService(session=session)


DictServiceDep = Annotated[DictService, Depends(get_dict_service)]
